package com.airlines.crewassignment.service.linkline.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.airlines.base.config.datasource.PrimaryDataSourceConfig;
import com.airlines.base.config.response.ResponseResult;
import com.airlines.base.config.response.ResponseResultBuilder;
import com.airlines.base.service.base.impl.BaseServiceImpl;
import com.airlines.common.ListSortUtil;
import com.airlines.common.WeekUtil;
import com.airlines.crewassignment.dao.linkline.TaskLoopMapper;
import com.airlines.crewassignment.domain.FlightInfo;
import com.airlines.crewassignment.entity.linkline.TaskLoop;
import com.airlines.crewassignment.entity.linkline.TaskLoopDay;
import com.airlines.crewassignment.entity.linkline.TaskLoopFlight;
import com.airlines.crewassignment.service.airport.AirportService;
import com.airlines.crewassignment.service.basicinfo.FoundationService;
import com.airlines.crewassignment.service.linkline.TaskLoopDayService;
import com.airlines.crewassignment.service.linkline.TaskLoopFlightService;
import com.airlines.crewassignment.service.linkline.TaskLoopService;

import mercury.framework.security.Authorization;

/**
 * @author xxxx
 * @date 2018年6月9日 
 * @description
 */
@Service
public class TaskLoopServiceImpl extends BaseServiceImpl<TaskLoop, Integer> implements TaskLoopService{
	@Autowired
	private TaskLoopMapper taskLoopMapper;
	@Autowired 
	@Override
	public void setBaseMapper() {
		super.setBaseMapper(taskLoopMapper);	
	}
	@Autowired
	private TaskLoopDayService taskLoopDayService;
	@Autowired
	private TaskLoopFlightService taskLoopFlightService;
	@Autowired
	private AirportService airprotService;
	@Autowired
	private FoundationService foundationService;
	
	@Override
	public TaskLoop getTaskLoopAll(int id) {
		TaskLoop taskLoop = this.getByPrimaryKey(id); 
		if(taskLoop == null){
			return null;
		}
		
		List<TaskLoopDay> dayList = taskLoopDayService.listTaskLoopDayByLoopId(id);
		List<TaskLoopFlight> flightList = taskLoopFlightService.listTaskLoopFlightByLoopId(id);
		
		
		for(TaskLoopDay day : dayList){
			for(TaskLoopFlight flight : flightList){
				if(day.getLoopDay().equals(flight.getLoopDay())
						&& day.getLoopId().equals(flight.getLoopId())){
					day.getFlightList().add(flight);
				}
			}
			ListSortUtil.sort(day.getFlightList(), true, "td");
		}
		ListSortUtil.sort(dayList, true, "loopDay");
		taskLoop.setDayList(dayList);
		return taskLoop;
	}

	@Override
	public int disable(int taskLoopId) {
		TaskLoop taskLoop = new TaskLoop();
		taskLoop.setId(taskLoopId);
		taskLoop.setStatus(0);
		return this.updateByPrimaryKeySelective(taskLoop);
	}
	@Override
	public ResponseResult<String> saveCk(TaskLoop taskLoop) {
		List<TaskLoopDay> dayList  = taskLoop.getDayList();
		String weeks = taskLoop.getWeekFristDay();
		List<TaskLoopFlight> flightListAll = new ArrayList<>();
		for(TaskLoopDay day : dayList){
			List<TaskLoopFlight> flightList = day.getFlightList();
			for(TaskLoopFlight flight : flightList){
				String weekFlight = WeekUtil.getWeeksNext(weeks, day.getLoopDay()-1);
				flight.setWeeks(weekFlight);
				flightListAll.add(flight);
			}
		}
		if(CollectionUtils.isEmpty(flightListAll)){
			return ResponseResultBuilder.errorResult(null, "航班列表为空", null);
		}
		
		TaskLoopFlight frist = flightListAll.get(0);
		if(!foundationService.isBase(frist.getDepartureAirport(), taskLoop.getDutyCode())){
			return ResponseResultBuilder.errorResult(null, "任务环开始不是基地", null);
		}
		
		TaskLoopFlight end = flightListAll.get(flightListAll.size()-1);
		if(!foundationService.isBase(end.getArrivalAirport(), taskLoop.getDutyCode())){
			return ResponseResultBuilder.errorResult(null, "任务环结束不是基地", null);
		}
		
		
		//同一个航班号，起飞目的，相同的时间范围内的班期，不能重复定义
		/*
		TaskLoop query = new TaskLoop();
		query.setDutyCode(taskLoop.getDutyCode());
		List<TaskLoop> indbList = this.listData(query);
		DateTimeRange dateTimeRange = new DateTimeRange(taskLoop.getStartDate(),taskLoop.getEndDate());
		for(TaskLoop indb : indbList){
			DateTimeRange dateTimeRangeIndb = new DateTimeRange(indb.getStartDate(),indb.getEndDate());
			TaskLoop indbAll = this.getTaskLoopAll(indb.getId());
			for(TaskLoopDay day : indbAll.getDayList()){
				for(TaskLoopFlight tfIndb : day.getFlightList()){
					for(TaskLoopFlight tf : flightListAll){
						if(StringUtils.equals(tf.getFlightNo(), tfIndb.getFlightNo())
								&& StringUtils.equals(tf.getDepartureAirport(), tfIndb.getDepartureAirport())
								&& StringUtils.equals(tf.getArrivalAirport(), tfIndb.getArrivalAirport())
								&& WeekUtil.isIntersection(dateTimeRange, tf.getWeeks(), dateTimeRangeIndb, tfIndb.getWeeks())){
							return ResponseResultBuilder.errorResult(null, tf.getFlightInfo()+tf.getDepartureAirport()+tf.getArrivalAirport()+"在其他任务环中已经定义", null);
						}
					}
				}
			}
		}
	*/
		
		return ResponseResultBuilder.successResult();
	}

	@Transactional(transactionManager = PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	@Override
	public void saveAll(TaskLoop taskLoop) {
		Date updateTime = new Date();
		String updateBy =  Authorization.getUser().getUserNo();
		String loopName = this.getLoopName(taskLoop);
		
		taskLoop.setLoopName(loopName);
		taskLoop.setStatus(1);
		taskLoop.setUpdateBy(updateBy);
		taskLoop.setUpdateTime(updateTime);
		this.saveOrUpdate(taskLoop);
		
		List<TaskLoopDay> dayList  = taskLoop.getDayList();
		if(taskLoop.getId() != null){
			TaskLoop indb  = this.getTaskLoopAll(taskLoop.getId());
			//删除不存在天信息
			this.delete(dayList, indb.getDayList());
		}
		
		String weeks = taskLoop.getWeekFristDay();
		for(TaskLoopDay day : dayList){
			day.setLoopId(taskLoop.getId());
			day.setUpdateBy(updateBy);
			day.setUpdateTime(updateTime);
			taskLoopDayService.saveOrUpdate(day);
			
			List<TaskLoopFlight> flightList = day.getFlightList();
			
			for(TaskLoopFlight flight : flightList){
				String weekFlight = WeekUtil.getWeeksNext(weeks, day.getLoopDay()-1);
				flight.setWeeks(weekFlight);
				flight.setLoopId(taskLoop.getId());
				flight.setUpdateBy(updateBy);
				flight.setUpdateTime(updateTime);
				taskLoopFlightService.saveOrUpdate(flight);
			}
		}
			
			
	}
	
	@Transactional(transactionManager = PrimaryDataSourceConfig.TRANSACTION_MANAGER)
	private void delete(List<TaskLoopDay> newList,List<TaskLoopDay> dbList){
		for(TaskLoopDay indb : dbList){
			boolean deleteFlag = true;
			for(TaskLoopDay newDay : newList){
				if(indb.getId().equals(newDay.getId())){
					deleteFlag = false;
				}
			}
			if(deleteFlag){
				taskLoopDayService.deleteByPrimaryKey(indb.getId());
				//删除该天下的航班
				TaskLoopFlight taskLoopFlightQuery = new TaskLoopFlight();
				taskLoopFlightQuery.setLoopId(indb.getLoopId());
				taskLoopFlightQuery.setLoopDay(indb.getLoopDay());
				List<TaskLoopFlight> taskLoopFlightDeleteList = taskLoopFlightService.listData(taskLoopFlightQuery);
				for(TaskLoopFlight f : taskLoopFlightDeleteList){
					taskLoopFlightService.deleteByPrimaryKey(f.getId());
				}
				
			}
		}
	}

	@Override
	public int saveOrUpdate(TaskLoop taskLoop) {
		if(taskLoop.getId() == null){
			return this.save(taskLoop);
		}else{
			return this.updateByPrimaryKey(taskLoop);
		}
	}
	
	/**
	 * 根据每天的航班，自动生成任务环名称
	 * @param taskLoop
	 * @return
	 */
	private String getLoopName(TaskLoop taskLoop){
		List<TaskLoopDay> dayList = taskLoop.getDayList();
		ListSortUtil.sort(dayList, true, "loopDay");
		StringBuffer sb = new StringBuffer();
		sb.append("");
		for(TaskLoopDay day : dayList){
			List<TaskLoopFlight> flightList = day.getFlightList();
			sb.append("-");
			if(CollectionUtils.isEmpty(flightList)){
				sb.append("夜");
			}else{
				List<FlightInfo> flightInfoList = new ArrayList<>();
				for(TaskLoopFlight f : flightList){
					FlightInfo flightInfo = new FlightInfo();
					flightInfo.setDepartureAirport(f.getDepartureAirport());
					flightInfo.setArrivalAirport(f.getArrivalAirport());
					flightInfoList.add(flightInfo);
				}
				String cityAbbrLine = airprotService.getShortCityLine(flightInfoList,null);
				sb.append(cityAbbrLine);
				
			}
			sb.append("-");
		}
		sb.delete(0, 1);
		sb.delete(sb.length()-1, sb.length());
		return sb.toString();
	}

	
}
